package carassius.GUI;

import carassius.BLL.Events.AquariumType.AquariumTypeAddedListener;
import carassius.BLL.Events.AquariumType.AquariumTypeRemovedListener;
import carassius.DAL.AquariumRow;
import carassius.DAL.AquariumTypeRow;
import carassius.DAL.Database;
import carassius.DAL.OptimalAquariumWaterConditionRow;
import carassius.DAL.WaterConditionRow;
import java.awt.Frame;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ResourceBundle;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;

/**
 *
 * @author siebz0r
 */
public class AquariumForm
		extends javax.swing.JDialog
		implements AquariumTypeAddedListener,
				   AquariumTypeRemovedListener
{
	//<editor-fold defaultstate="collapsed" desc="Fields">
	private AquariumRow _aquariumRow;
	//</editor-fold>

	//<editor-fold defaultstate="collapsed" desc="Constructors">
	/** Creates new form AquariumForm */
	public AquariumForm(Frame parent)
	{
		this(parent, null);
	}

	public AquariumForm(Frame parent, AquariumRow aquariumRow)
	{
		super(parent, true);
		_aquariumRow = aquariumRow;
		initComponents();
		fillAquariumTypeList();
		Database.getAquariumTypeTable().addAquariumTypeAddedEventListener(this);
		Database.getAquariumTypeTable().addAquariumTypeRemovedEventListener(this);

		fillWaterConditionTableWithWaterConditions();

		if (_aquariumRow != null)
		{
			uxNameTextField.setText(_aquariumRow.getName());
			uxTypeComboBox.setSelectedItem(_aquariumRow.getType());
			uxLengthIntegerTextField.setValue(_aquariumRow.getLength());
			uxWidthIntegerTextField.setValue(_aquariumRow.getWidth());
			uxHeigthIntegerTextField.setValue(_aquariumRow.getHeight());
			uxLightingTextArea.setText(_aquariumRow.getLighting());
			uxFilteringTextArea.setText(_aquariumRow.getFiltering());
			uxHeatingTextArea.setText(_aquariumRow.getHeating());
			uxCO2TextArea.setText(_aquariumRow.getCO2());
			calculateVolume();
			fillWaterConditionTableWithOptimalWaterConditions();
		}
	}
	//</editor-fold>

	//<editor-fold defaultstate="collapsed" desc="Private Methods">
	private void fillWaterConditionTableWithWaterConditions()
	{
		DefaultTableModel model = (DefaultTableModel) uxOptimalWaterValuesTable.getModel();
		try
		{
			//get all water condition rows
			Collection<WaterConditionRow> waterConditionRows = Database.getWaterConditionTable().getAll();
			for (WaterConditionRow row : waterConditionRows)
			{
				boolean added = false;
				//check if the row exists in the table
				for (int i = 0; i < model.getRowCount(); i++)
				{
					if (row.equals(model.getValueAt(i, 0)))
					{
						added = true;
						break; //row exists in table, skip add to table
					}
				}
				if (!added)
				{
					//row doesn't exist in table so we add it here :-)
					model.addRow(new Object[]
							{
								row, null, null
							});
				}
			}
		}
		catch (SQLException ex)
		{
			//something went wrong while getting water conditions, saving of these is disabled to prevent another error
			model.setRowCount(0);
			StringBuilder sb = new StringBuilder();
			sb.append(ResourceBundle.getBundle("carassius.resources.Messages").getString("FetchWaterConditionsError"));
			sb.append("\n");
			sb.append(ResourceBundle.getBundle("carassius.resources.Messages").getString("SaveOptimalWaterConditionsIsDisabledMessage"));

			JOptionPane.showMessageDialog(this,
					sb.toString(),
					ResourceBundle.getBundle("carassius.resources.Messages").getString("FetchWaterConditionsError"),
					JOptionPane.WARNING_MESSAGE);
		}
	}

	private void fillWaterConditionTableWithOptimalWaterConditions()
	{
		if (_aquariumRow instanceof AquariumRow)
		{
			DefaultTableModel model = (DefaultTableModel) uxOptimalWaterValuesTable.getModel();

			try
			{
				ArrayList<OptimalAquariumWaterConditionRow> optimalAquariumWaterConditionRows = Database.getOptimalAquariumWaterConditionTable().getByAquariumId(_aquariumRow.getId());
				for (OptimalAquariumWaterConditionRow row : optimalAquariumWaterConditionRows)
				{
					boolean added = false;

					for (int i = 0; i < model.getRowCount(); i++)
					{
						if (row.getCondition().equals(model.getValueAt(i, 0)))
						{
							//replace the water condition with the optimal water condition
							model.setValueAt(row, i, 0);
							model.setValueAt(row.getMinValue(), i, 1);
							model.setValueAt(row.getMaxValue(), i, 2);
							added = true;
							break;
						}
						else if (row.equals(model.getValueAt(i, 0)))
						{
							//optimal water condition exists, nothing to do here
							added = true;
							break;
						}
					}
					if (!added)
					{
						//if row wasn't added to the table, do so now
						model.addRow(new Object[]
								{
									row, row.getMinValue(), row.getMaxValue()
								});
					}
				}
			}
			catch (SQLException ex)
			{
				uxSaveButton.setEnabled(false);
				StringBuilder msg = new StringBuilder();
				msg.append(ResourceBundle.getBundle("carassius.resources.Messages").getString("FetchWaterConditionsError"));
				msg.append("\n");
				msg.append(ResourceBundle.getBundle("carassius.resources.Messages").getString("SaveIsDisabledMessage"));

				JOptionPane.showMessageDialog(this,
						msg.toString(),
						ResourceBundle.getBundle("carassius.resources.Messages").getString("FetchWaterConditionsErrorTitle"),
						JOptionPane.ERROR_MESSAGE);
			}
		}
	}

	private void calculateVolume()
	{
		Integer length = uxLengthIntegerTextField.getValue();
		Integer width = uxWidthIntegerTextField.getValue();
		Integer height = uxHeigthIntegerTextField.getValue();

		if (length instanceof Integer
				&& width instanceof Integer
				&& height instanceof Integer)
		{
			uxVolumeLabel.setText(Integer.toString((length * width * height) / 1000));
		}
		else
		{
			uxVolumeLabel.setText("-");
		}
	}

	private void fillAquariumTypeList()
	{
		try
		{
			Collection<AquariumTypeRow> types = Database.getAquariumTypeTable().getAll();
			DefaultComboBoxModel model = (DefaultComboBoxModel) uxTypeComboBox.getModel();
			model.removeAllElements();

			if (types != null)
			{
				for (AquariumTypeRow r : types)
				{
					model.addElement(r);
				}
			}
		}
		catch (SQLException ex)
		{
			StringBuilder msg = new StringBuilder();
			msg.append(ResourceBundle.getBundle("carassius.resources.Messages").getString("FetchAquariumTypesError"));
			msg.append("\n");
			msg.append(ResourceBundle.getBundle("carassius.resources.Messages").getString("SaveIsDisabledMessage"));
			JOptionPane.showMessageDialog(this,
					msg.toString(),
					ResourceBundle.getBundle("carassius.resources.Messages").getString("FetchAquariumTypesErrorTitle"),
					JOptionPane.ERROR_MESSAGE);
			uxSaveButton.setEnabled(false);
		}
	}

	private boolean inputIsValid()
	{
		return(uxOptimalWaterValuesTable.isInputValid());
	}
	//</editor-fold>

	//<editor-fold defaultstate="collapsed" desc="Public Methods">
	@Override
	public void dispose()
	{
		Database.getAquariumTypeTable().removeAquariumTypeAddedEventListener(this);
		Database.getAquariumTypeTable().removeAquariumTypeRemovedEventListener(this);
		super.dispose();
	}
	//</editor-fold>

	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        uxNameTextField = new TextFieldWithMenu();
        uxNamePrefixLabel = new javax.swing.JLabel();
        uxMeasurementsPanel = new javax.swing.JPanel();
        uxLengthPrefixLabel = new javax.swing.JLabel();
        uxWidthPrefixLabel = new javax.swing.JLabel();
        uxHeightPrefixLabel = new javax.swing.JLabel();
        uxLengthIntegerTextField = new carassius.GUI.IntegerTextField();
        uxWidthIntegerTextField = new carassius.GUI.IntegerTextField();
        uxHeigthIntegerTextField = new carassius.GUI.IntegerTextField();
        uxVolumePanel = new javax.swing.JPanel();
        uxVolumePrefixLabel = new javax.swing.JLabel();
        uxVolumeLabel = new javax.swing.JLabel();
        uxVolumePostfixLabel = new javax.swing.JLabel();
        uxButtonPanel = new javax.swing.JPanel();
        uxCancelButton = new javax.swing.JButton();
        uxSaveButton = new javax.swing.JButton();
        uxLowerPanel = new javax.swing.JPanel();
        uxFilteringPanel = new javax.swing.JPanel();
        uxFilteringScrollPane = new javax.swing.JScrollPane();
        uxFilteringTextArea = new TextAreaWithMenu();
        uxHeatingPanel = new javax.swing.JPanel();
        uxHeatingScrollPane = new javax.swing.JScrollPane();
        uxHeatingTextArea = new TextAreaWithMenu();
        uxCO2Panel = new javax.swing.JPanel();
        uxCO2ScrollPane = new javax.swing.JScrollPane();
        uxCO2TextArea = new TextAreaWithMenu();
        uxLightingPanel = new javax.swing.JPanel();
        uxLightingScrollPane = new javax.swing.JScrollPane();
        uxLightingTextArea = new TextAreaWithMenu();
        uxOptimalWaterConditionsPanel = new javax.swing.JPanel();
        uxOptimalWaterValuesScrollPane = new javax.swing.JScrollPane();
        uxOptimalWaterValuesTable = new carassius.GUI.WaterValuesTable();
        uxTypePanel = new javax.swing.JPanel();
        uxTypeComboBox = new javax.swing.JComboBox();
        uxTypeButtonPanel = new javax.swing.JPanel();
        uxTypeAddButton = new javax.swing.JButton();
        uxTypeRemoveButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("carassius/GUI/resources/AquariumForm"); // NOI18N
        setTitle(bundle.getString((_aquariumRow instanceof AquariumRow) ? "Form.title.edit" : "Form.title.add")); // NOI18N
        setName("Form"); // NOI18N
        getContentPane().setLayout(new java.awt.GridBagLayout());

        uxNameTextField.setName("uxNameTextField"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 5);
        getContentPane().add(uxNameTextField, gridBagConstraints);

        uxNamePrefixLabel.setText(bundle.getString("uxNamePrefixLabel.text")); // NOI18N
        uxNamePrefixLabel.setName("uxNamePrefixLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 0, 5);
        getContentPane().add(uxNamePrefixLabel, gridBagConstraints);

        uxMeasurementsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(bundle.getString("uxMeasurementsPanel.border.title"))); // NOI18N
        uxMeasurementsPanel.setName("uxMeasurementsPanel"); // NOI18N
        uxMeasurementsPanel.setLayout(new java.awt.GridBagLayout());

        uxLengthPrefixLabel.setText(bundle.getString("uxLengthPrefixLabel.text")); // NOI18N
        uxLengthPrefixLabel.setName("uxLengthPrefixLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.ipadx = 5;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 0, 0);
        uxMeasurementsPanel.add(uxLengthPrefixLabel, gridBagConstraints);

        uxWidthPrefixLabel.setText(bundle.getString("uxWidthPrefixLabel.text")); // NOI18N
        uxWidthPrefixLabel.setName("uxWidthPrefixLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.ipadx = 5;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 0, 0);
        uxMeasurementsPanel.add(uxWidthPrefixLabel, gridBagConstraints);

        uxHeightPrefixLabel.setText(bundle.getString("uxHeightPrefixLabel.text")); // NOI18N
        uxHeightPrefixLabel.setName("uxHeightPrefixLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.ipadx = 5;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 0);
        uxMeasurementsPanel.add(uxHeightPrefixLabel, gridBagConstraints);

        uxLengthIntegerTextField.setName("uxLengthIntegerTextField"); // NOI18N
        uxLengthIntegerTextField.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                uxLengthIntegerTextFieldCaretUpdate(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        uxMeasurementsPanel.add(uxLengthIntegerTextField, gridBagConstraints);

        uxWidthIntegerTextField.setName("uxWidthIntegerTextField"); // NOI18N
        uxWidthIntegerTextField.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                uxWidthIntegerTextFieldCaretUpdate(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        uxMeasurementsPanel.add(uxWidthIntegerTextField, gridBagConstraints);

        uxHeigthIntegerTextField.setName("uxHeigthIntegerTextField"); // NOI18N
        uxHeigthIntegerTextField.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                uxHeigthIntegerTextFieldCaretUpdate(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        uxMeasurementsPanel.add(uxHeigthIntegerTextField, gridBagConstraints);

        uxVolumePanel.setName("uxVolumePanel"); // NOI18N
        uxVolumePanel.setLayout(new java.awt.GridBagLayout());

        uxVolumePrefixLabel.setText(bundle.getString("uxVolumePrefixLabel.text")); // NOI18N
        uxVolumePrefixLabel.setName("uxVolumePrefixLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 0);
        uxVolumePanel.add(uxVolumePrefixLabel, gridBagConstraints);

        uxVolumeLabel.setText("-"); // NOI18N
        uxVolumeLabel.setName("uxVolumeLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 0);
        uxVolumePanel.add(uxVolumeLabel, gridBagConstraints);

        uxVolumePostfixLabel.setText("L"); // NOI18N
        uxVolumePostfixLabel.setName("uxVolumePostfixLabel"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        uxVolumePanel.add(uxVolumePostfixLabel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.FIRST_LINE_START;
        uxMeasurementsPanel.add(uxVolumePanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 4;
        gridBagConstraints.ipadx = 100;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
        gridBagConstraints.insets = new java.awt.Insets(5, 0, 0, 5);
        getContentPane().add(uxMeasurementsPanel, gridBagConstraints);

        uxButtonPanel.setName("uxButtonPanel"); // NOI18N

        uxCancelButton.setText(bundle.getString("uxCancelButton.text")); // NOI18N
        uxCancelButton.setName("uxCancelButton"); // NOI18N
        uxCancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                uxCancelButtonActionPerformed(evt);
            }
        });
        uxButtonPanel.add(uxCancelButton);

        uxSaveButton.setText(bundle.getString("uxSaveButton.text")); // NOI18N
        uxSaveButton.setName("uxSaveButton"); // NOI18N
        uxSaveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                uxSaveButtonActionPerformed(evt);
            }
        });
        uxButtonPanel.add(uxSaveButton);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LAST_LINE_END;
        getContentPane().add(uxButtonPanel, gridBagConstraints);

        uxLowerPanel.setName("uxLowerPanel"); // NOI18N
        uxLowerPanel.setLayout(new java.awt.GridBagLayout());

        uxFilteringPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(bundle.getString("uxFilteringPanel.border.title"))); // NOI18N
        uxFilteringPanel.setName("uxFilteringPanel"); // NOI18N
        uxFilteringPanel.setLayout(new javax.swing.BoxLayout(uxFilteringPanel, javax.swing.BoxLayout.LINE_AXIS));

        uxFilteringScrollPane.setName("uxFilteringScrollPane"); // NOI18N

        uxFilteringTextArea.setColumns(20);
        uxFilteringTextArea.setLineWrap(true);
        uxFilteringTextArea.setRows(5);
        uxFilteringTextArea.setName("uxFilteringTextArea"); // NOI18N
        uxFilteringScrollPane.setViewportView(uxFilteringTextArea);

        uxFilteringPanel.add(uxFilteringScrollPane);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0.5;
        uxLowerPanel.add(uxFilteringPanel, gridBagConstraints);

        uxHeatingPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(bundle.getString("uxHeatingPanel.border.title"))); // NOI18N
        uxHeatingPanel.setName("uxHeatingPanel"); // NOI18N
        uxHeatingPanel.setLayout(new javax.swing.BoxLayout(uxHeatingPanel, javax.swing.BoxLayout.LINE_AXIS));

        uxHeatingScrollPane.setName("uxHeatingScrollPane"); // NOI18N

        uxHeatingTextArea.setColumns(20);
        uxHeatingTextArea.setLineWrap(true);
        uxHeatingTextArea.setRows(5);
        uxHeatingTextArea.setName("uxHeatingTextArea"); // NOI18N
        uxHeatingScrollPane.setViewportView(uxHeatingTextArea);

        uxHeatingPanel.add(uxHeatingScrollPane);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0.5;
        uxLowerPanel.add(uxHeatingPanel, gridBagConstraints);

        uxCO2Panel.setBorder(javax.swing.BorderFactory.createTitledBorder(bundle.getString("uxCO2Panel.border.title"))); // NOI18N
        uxCO2Panel.setName("uxCO2Panel"); // NOI18N
        uxCO2Panel.setLayout(new javax.swing.BoxLayout(uxCO2Panel, javax.swing.BoxLayout.LINE_AXIS));

        uxCO2ScrollPane.setName("uxCO2ScrollPane"); // NOI18N

        uxCO2TextArea.setColumns(20);
        uxCO2TextArea.setLineWrap(true);
        uxCO2TextArea.setRows(5);
        uxCO2TextArea.setName("uxCO2TextArea"); // NOI18N
        uxCO2ScrollPane.setViewportView(uxCO2TextArea);

        uxCO2Panel.add(uxCO2ScrollPane);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0.5;
        uxLowerPanel.add(uxCO2Panel, gridBagConstraints);

        uxLightingPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(bundle.getString("uxLightingPanel.border.title"))); // NOI18N
        uxLightingPanel.setName("uxLightingPanel"); // NOI18N
        uxLightingPanel.setLayout(new javax.swing.BoxLayout(uxLightingPanel, javax.swing.BoxLayout.LINE_AXIS));

        uxLightingScrollPane.setName("uxLightingScrollPane"); // NOI18N

        uxLightingTextArea.setColumns(20);
        uxLightingTextArea.setLineWrap(true);
        uxLightingTextArea.setRows(5);
        uxLightingTextArea.setName("uxLightingTextArea"); // NOI18N
        uxLightingScrollPane.setViewportView(uxLightingTextArea);

        uxLightingPanel.add(uxLightingScrollPane);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 0.5;
        uxLowerPanel.add(uxLightingPanel, gridBagConstraints);

        uxOptimalWaterConditionsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(bundle.getString("uxOptimalWaterConditionsPanel.border.title"))); // NOI18N
        uxOptimalWaterConditionsPanel.setName("uxOptimalWaterConditionsPanel"); // NOI18N
        uxOptimalWaterConditionsPanel.setLayout(new java.awt.CardLayout());

        uxOptimalWaterValuesScrollPane.setName("uxOptimalWaterValuesScrollPane"); // NOI18N

        uxOptimalWaterValuesTable.setName("uxOptimalWaterValuesTable"); // NOI18N
        uxOptimalWaterValuesScrollPane.setViewportView(uxOptimalWaterValuesTable);

        uxOptimalWaterConditionsPanel.add(uxOptimalWaterValuesScrollPane, "card2");

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.gridheight = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.VERTICAL;
        gridBagConstraints.ipadx = 135;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 5);
        uxLowerPanel.add(uxOptimalWaterConditionsPanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.gridheight = 4;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 0, 5);
        getContentPane().add(uxLowerPanel, gridBagConstraints);

        uxTypePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(bundle.getString("uxTypePanel.border.title"))); // NOI18N
        uxTypePanel.setName("uxTypePanel"); // NOI18N
        uxTypePanel.setLayout(new java.awt.GridBagLayout());

        uxTypeComboBox.setName("uxTypeComboBox"); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 5);
        uxTypePanel.add(uxTypeComboBox, gridBagConstraints);

        uxTypeButtonPanel.setName("uxTypeButtonPanel"); // NOI18N
        uxTypeButtonPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT));

        uxTypeAddButton.setText(bundle.getString("uxTypeAddButton.text")); // NOI18N
        uxTypeAddButton.setName("uxTypeAddButton"); // NOI18N
        uxTypeAddButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                uxTypeAddButtonActionPerformed(evt);
            }
        });
        uxTypeButtonPanel.add(uxTypeAddButton);

        uxTypeRemoveButton.setText(bundle.getString("uxTypeRemoveButton.text")); // NOI18N
        uxTypeRemoveButton.setName("uxTypeRemoveButton"); // NOI18N
        uxTypeRemoveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                uxTypeRemoveButtonActionPerformed(evt);
            }
        });
        uxTypeButtonPanel.add(uxTypeRemoveButton);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
        gridBagConstraints.weightx = 1.0;
        uxTypePanel.add(uxTypeButtonPanel, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
        getContentPane().add(uxTypePanel, gridBagConstraints);

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-450)/2, (screenSize.height-640)/2, 450, 640);
    }// </editor-fold>//GEN-END:initComponents

	private void uxSaveButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_uxSaveButtonActionPerformed
	{//GEN-HEADEREND:event_uxSaveButtonActionPerformed
		if (inputIsValid())
		{
			try
			{
				String name = uxNameTextField.getText().trim();
				Integer length = uxLengthIntegerTextField.getValue();
				Integer width = uxWidthIntegerTextField.getValue();
				Integer height = uxHeigthIntegerTextField.getValue();
				AquariumTypeRow type = (AquariumTypeRow) uxTypeComboBox.getSelectedItem();
				String lighting = uxLightingTextArea.getText().trim();
				String heating = uxHeatingTextArea.getText().trim();
				String filtering = uxFilteringTextArea.getText().trim();
				String CO2 = uxCO2TextArea.getText().trim();

				if (_aquariumRow instanceof AquariumRow)
				{
					_aquariumRow.setName(name);
					_aquariumRow.setLength(length);
					_aquariumRow.setWidth(width);
					_aquariumRow.setHeight(height);
					_aquariumRow.setType(type);
					_aquariumRow.setLighting(lighting);
					_aquariumRow.setHeating(heating);
					_aquariumRow.setFiltering(filtering);
					_aquariumRow.setCO2(CO2);
				}
				else
				{
					_aquariumRow = Database.getAquariumTable().add(name, length, width, height, type, lighting, heating, filtering, CO2);
				}

				if (_aquariumRow != null)
				{
					DefaultTableModel model = (DefaultTableModel) uxOptimalWaterValuesTable.getModel();
					for (int i = 0; i < model.getRowCount(); i++)
					{
						Object val = model.getValueAt(i, 0);
						Double minVal = (Double) model.getValueAt(i, 1);
						Double maxVal = (Double) model.getValueAt(i, 2);

						if (val instanceof WaterConditionRow)
						{
							if (minVal != null || maxVal != null)
							{
								WaterConditionRow wcr = (WaterConditionRow) val;
								OptimalAquariumWaterConditionRow oawcr = Database.getOptimalAquariumWaterConditionTable().add(_aquariumRow, wcr, minVal, maxVal);
								model.setValueAt(oawcr, i, 0);
							}
						}
						else if (val instanceof OptimalAquariumWaterConditionRow)
						{
							OptimalAquariumWaterConditionRow oawcr = (OptimalAquariumWaterConditionRow) val;
							if (minVal != null || maxVal != null)
							{
								oawcr.setMinValue(minVal);
								oawcr.setMaxValue(maxVal);
							}
							else
							{
								Database.getOptimalAquariumWaterConditionTable().delete(oawcr);
								model.setValueAt(oawcr.getCondition(), i, 0);
							}
						}
					}
				}
				JOptionPane.showMessageDialog(this,
						ResourceBundle.getBundle("carassius.resources.Messages").getString("AquariumSaved"),
						ResourceBundle.getBundle("carassius.resources.Messages").getString("AquariumSavedTitle"),
						JOptionPane.INFORMATION_MESSAGE);
				dispose();
			}
			catch (NumberFormatException ex)
			{
				JOptionPane.showMessageDialog(this,
						ResourceBundle.getBundle("carassius.resources.Messages").getString("GenericWrongInputError"),
						ResourceBundle.getBundle("carassius.resources.Messages").getString("GenericWrongInputErrorTitle"),
						JOptionPane.ERROR_MESSAGE);
			}
			catch (SQLException ex)
			{
				System.out.println(ex.toString());
				JOptionPane.showMessageDialog(this,
						ResourceBundle.getBundle("carassius.resources.Messages").getString("AquariumSavedError"),
						ResourceBundle.getBundle("carassius.resources.Messages").getString("AquariumSavedErrorTitle"),
						JOptionPane.ERROR_MESSAGE);
			}
		}
	}//GEN-LAST:event_uxSaveButtonActionPerformed

	private void uxTypeAddButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_uxTypeAddButtonActionPerformed
	{//GEN-HEADEREND:event_uxTypeAddButtonActionPerformed
		AquariumTypeForm frm = new AquariumTypeForm(this);
		frm.setVisible(true);
	}//GEN-LAST:event_uxTypeAddButtonActionPerformed

	private void uxTypeRemoveButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_uxTypeRemoveButtonActionPerformed
	{//GEN-HEADEREND:event_uxTypeRemoveButtonActionPerformed
		DefaultComboBoxModel model = (DefaultComboBoxModel) uxTypeComboBox.getModel();
		AquariumTypeRow row = (AquariumTypeRow) uxTypeComboBox.getSelectedItem();

		try
		{
			if (Database.getAquariumTypeTable().delete(row))
			{
				model.removeElement(row);
			}
		}
		catch (SQLException ex)
		{
			JOptionPane.showMessageDialog(this,
					ResourceBundle.getBundle("carassius.resources.Messages").getString("RemoveAquariumTypesError"),
					ResourceBundle.getBundle("carassius.resources.Messages").getString("RemoveAquariumTypesErrorTitle"),
					JOptionPane.ERROR_MESSAGE);
		}
	}//GEN-LAST:event_uxTypeRemoveButtonActionPerformed

	private void uxCancelButtonActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_uxCancelButtonActionPerformed
	{//GEN-HEADEREND:event_uxCancelButtonActionPerformed
		dispose();
	}//GEN-LAST:event_uxCancelButtonActionPerformed

	private void uxHeigthIntegerTextFieldCaretUpdate(//GEN-FIRST:event_uxHeigthIntegerTextFieldCaretUpdate
			javax.swing.event.CaretEvent evt)
	{//GEN-HEADEREND:event_uxHeigthIntegerTextFieldCaretUpdate
		calculateVolume();
	}//GEN-LAST:event_uxHeigthIntegerTextFieldCaretUpdate

	private void uxWidthIntegerTextFieldCaretUpdate(//GEN-FIRST:event_uxWidthIntegerTextFieldCaretUpdate
			javax.swing.event.CaretEvent evt)
	{//GEN-HEADEREND:event_uxWidthIntegerTextFieldCaretUpdate
		calculateVolume();
	}//GEN-LAST:event_uxWidthIntegerTextFieldCaretUpdate

	private void uxLengthIntegerTextFieldCaretUpdate(//GEN-FIRST:event_uxLengthIntegerTextFieldCaretUpdate
			javax.swing.event.CaretEvent evt)
	{//GEN-HEADEREND:event_uxLengthIntegerTextFieldCaretUpdate
		calculateVolume();
	}//GEN-LAST:event_uxLengthIntegerTextFieldCaretUpdate
	//<editor-fold defaultstate="collapsed" desc="Variables declaration">
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel uxButtonPanel;
    private javax.swing.JPanel uxCO2Panel;
    private javax.swing.JScrollPane uxCO2ScrollPane;
    private javax.swing.JTextArea uxCO2TextArea;
    private javax.swing.JButton uxCancelButton;
    private javax.swing.JPanel uxFilteringPanel;
    private javax.swing.JScrollPane uxFilteringScrollPane;
    private javax.swing.JTextArea uxFilteringTextArea;
    private javax.swing.JPanel uxHeatingPanel;
    private javax.swing.JScrollPane uxHeatingScrollPane;
    private javax.swing.JTextArea uxHeatingTextArea;
    private javax.swing.JLabel uxHeightPrefixLabel;
    private carassius.GUI.IntegerTextField uxHeigthIntegerTextField;
    private carassius.GUI.IntegerTextField uxLengthIntegerTextField;
    private javax.swing.JLabel uxLengthPrefixLabel;
    private javax.swing.JPanel uxLightingPanel;
    private javax.swing.JScrollPane uxLightingScrollPane;
    private javax.swing.JTextArea uxLightingTextArea;
    private javax.swing.JPanel uxLowerPanel;
    private javax.swing.JPanel uxMeasurementsPanel;
    private javax.swing.JLabel uxNamePrefixLabel;
    private javax.swing.JTextField uxNameTextField;
    private javax.swing.JPanel uxOptimalWaterConditionsPanel;
    private javax.swing.JScrollPane uxOptimalWaterValuesScrollPane;
    private carassius.GUI.WaterValuesTable uxOptimalWaterValuesTable;
    private javax.swing.JButton uxSaveButton;
    private javax.swing.JButton uxTypeAddButton;
    private javax.swing.JPanel uxTypeButtonPanel;
    private javax.swing.JComboBox uxTypeComboBox;
    private javax.swing.JPanel uxTypePanel;
    private javax.swing.JButton uxTypeRemoveButton;
    private javax.swing.JLabel uxVolumeLabel;
    private javax.swing.JPanel uxVolumePanel;
    private javax.swing.JLabel uxVolumePostfixLabel;
    private javax.swing.JLabel uxVolumePrefixLabel;
    private carassius.GUI.IntegerTextField uxWidthIntegerTextField;
    private javax.swing.JLabel uxWidthPrefixLabel;
    // End of variables declaration//GEN-END:variables
	//</editor-fold>

	//<editor-fold defaultstate="collapsed" desc="Events">
	//<editor-fold defaultstate="collapsed" desc="Aquarium Type">
	@Override
	public void aquariumTypeAdded(AquariumTypeRow row)
	{
		DefaultComboBoxModel model = (DefaultComboBoxModel) uxTypeComboBox.getModel();
		model.addElement(row);
	}

	@Override
	public void aquariumTypeRemoved(AquariumTypeRow row)
	{
		DefaultComboBoxModel model = (DefaultComboBoxModel) uxTypeComboBox.getModel();
		model.removeElement(row);
	}
	//</editor-fold>
	//</editor-fold>
}
